// https://leetcode.cn/problems/print-zero-even-odd/
// Created by ade on 2022/11/2.
//

class ZeroEvenOdd {
private:
    int n;
    mutex mtx0, mtx1, mtx2;

public:
    ZeroEvenOdd(int n) {
        this->n = n;
        mtx1.lock();
        mtx2.lock();
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero(function<void(int)> printNumber) {
        for (int i = 1; i <= n; i++) {
            mtx0.lock();
            printNumber(0);
            if (i % 2 == 1) {
                mtx1.unlock();
            } else {
                mtx2.unlock();
            }
        }
    }

    void odd(function<void(int)> printNumber) {
        for (int i = 1; i <= n; i = i + 2) {
            mtx1.lock();
            printNumber(i);
            mtx0.unlock();
        }
    }

    void even(function<void(int)> printNumber) {
        for (int i = 2; i <= n; i = i + 2) {
            mtx2.lock();
            printNumber(i);
            mtx0.unlock();
        }
    }
};